package com.spsoft.core.utils;

import cn.hutool.extra.servlet.ServletUtil;
import com.alibaba.fastjson.JSONObject;
import eu.bitwalker.useragentutils.Browser;
import eu.bitwalker.useragentutils.UserAgent;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springframework.web.bind.ServletRequestUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.nio.charset.StandardCharsets;
import java.util.Objects;

/**
 * @author zjh
 * @version V1.0.0
 * @date 2020-12-2 16:27
 * @since 1.0
 */
@Slf4j
public class ServletUtils extends ServletRequestUtils {
    public final static String LOCAL_IP = "127.0.0.1";

    public final static String LOCAL_ADDRESS = "0:0:0:0:0:0:0:1";

    /**
     * 获取客户端IP
     *
     * <p>
     * 默认检测的Header:
     *
     * <pre>
     * 1、X-Forwarded-For
     * 2、X-Real-IP
     * 3、Proxy-Client-IP
     * 4、WL-Proxy-Client-IP
     * </pre>
     *
     * <p>
     * otherHeaderNames参数用于自定义检测的Header<br>
     * 需要注意的是，使用此方法获取的客户IP地址必须在Http服务器（例如Nginx）中配置头信息，否则容易造成IP伪造。
     * </p>
     *
     * @param request          请求对象{@link HttpServletRequest}
     * @param otherHeaderNames 其他自定义头文件，通常在Http服务器（例如Nginx）中配置
     * @return IP地址
     */
    public static String getIpByRequest(HttpServletRequest request, String... otherHeaderNames) {
        String ip = ServletUtil.getClientIP(request, otherHeaderNames);
        if (LOCAL_IP.equals(ip) || LOCAL_ADDRESS.equals(ip)) {
            // 获取本机真正的ip地址
            try {
                ip = InetAddress.getLocalHost().getHostAddress();
            } catch (UnknownHostException e) {
                log.error(e.getMessage(), e);
            }
        }
        return ip;
    }

    public static String getIpByHeaderNames(String... otherHeaderNames) {
        String ip = ServletUtil.getClientIP(getHttpServletRequest(), otherHeaderNames);
        if (LOCAL_IP.equals(ip) || LOCAL_ADDRESS.equals(ip)) {
            // 获取本机真正的ip地址
            try {
                ip = InetAddress.getLocalHost().getHostAddress();
            } catch (UnknownHostException e) {
                log.error(e.getMessage(), e);
            }
        }
        return ip;
    }

    public static String getIp() {
        String ip = ServletUtil.getClientIP(getHttpServletRequest());
        if (LOCAL_IP.equals(ip) || LOCAL_ADDRESS.equals(ip)) {
            // 获取本机真正的ip地址
            try {
                ip = InetAddress.getLocalHost().getHostAddress();
            } catch (UnknownHostException e) {
                log.error(e.getMessage(), e);
            }
        }
        return ip;
    }

    public static String getBrowser(HttpServletRequest request) {
        UserAgent userAgent = UserAgent.parseUserAgentString(request.getHeader("User-Agent"));
        Browser browser = userAgent.getBrowser();
        return browser.getName();
    }

    /**
     * 获取post参数
     *
     * @param tClass
     * @param <T>
     * @return
     */
    public static <T> T getPostParams(Class<T> tClass) {
        HttpServletRequest request = getHttpServletRequest();
        String postParams = null;
        try {
            postParams = IOUtils.toString(
                    new BufferedReader(new InputStreamReader(request.getInputStream(),
                            StandardCharsets.UTF_8)));
        } catch (IOException e) {
            e.printStackTrace();
        }
        return JSONObject.parseObject(postParams, tClass);
    }

    /**
     * 获取post参数
     *
     * @return
     */
    public static JSONObject getPostParams() {
        HttpServletRequest request = getHttpServletRequest();
        String postParams = null;
        try {
            postParams = IOUtils.toString(
                    new BufferedReader(new InputStreamReader(request.getInputStream(),
                            StandardCharsets.UTF_8)));
        } catch (IOException e) {
            postParams = new JSONObject().toJSONString();
            e.printStackTrace();
        }
        return JSONObject.parseObject(postParams);
    }

    /**
     * 获取字符串post参数
     *
     * @return
     */
    public static String getStringPostParams() {
        HttpServletRequest request = getHttpServletRequest();
        String postParams = null;
        try {
            postParams = IOUtils.toString(
                    new BufferedReader(new InputStreamReader(request.getInputStream(),
                            StandardCharsets.UTF_8)));
        } catch (IOException e) {
            e.printStackTrace();
        }
        return postParams;
    }

    public static HttpServletRequest getHttpServletRequest() {
        return ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
    }

    public static HttpServletResponse getHttpServletResponse() {
        return ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getResponse();
    }

    public static void setAttribute(String name, Object o) {
        HttpServletRequest request = getHttpServletRequest();
        request.setAttribute(name, o);
    }

    public static Object getAttribute(String name) {
        HttpServletRequest request = getHttpServletRequest();
        return request.getAttribute(name);
    }
}
